﻿#include "GraphModelProvider.h"

// App
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

// Data
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoCommand.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscNodeList.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysBeam.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysAbsShell.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysCavity.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysSemiInfiniteFluid.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEFace.h"
#include "FITK_Component/FITKAcousticsModel/FITKFESubSysAcoustic.h"
#include "FITK_Component/FITKAcousticsModel/FITKFESubSysStructure.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSensors.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractFESubSys.h"

// Render VTK
#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphRender.h"

// Graph
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObject3D.h"

// View
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKViewAdaptorBase.h"

namespace GraphData
{
    GraphModelProvider::GraphModelProvider(Comp::FITKGraph3DWindowVTK* graphWidget)
        : GraphProviderBase(graphWidget)
    {

    }

    GraphModelProvider::~GraphModelProvider()
    {
        // 析构三维可视化对象。
        deleteObjsHash(m_geoObjHash);
        deleteObjsHash(m_meshObjHash);
        deleteObjsHash(m_nodesObjHash);
        deleteObjsHash(m_SEABeamObjHash);

#if SUBSYSTEM_MERGE
        deleteObjsHash(m_SEAShellsObjHash);
        deleteObjsHash(m_SEACavitiesObjHash);
#else
        deleteObjsHash(m_SEAShellObjHash);
        deleteObjsHash(m_SEACavityObjHash);
#endif

        deleteObjsHash(m_SEASemiInfFluidObjHash);   
    }

    QString GraphModelProvider::getClassName()
    {
        return "GraphModelProvider";
    }

    bool GraphModelProvider::updateObjById(int dataId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* obj = getCurrentGraphObjByDataId(dataId);
        if (!obj)
        {
            return false;
        }

        obj->update(forceUpdate);

        return true;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getCurrentGraphObjs()
    {
        // 当前所有可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // 模型（几何）可视化对象。
        objs << m_geoObjHash.values();

        // 部件网格可视化对象。
        objs << m_meshObjHash.values();

        // SEA节点可视化对象。
        objs << m_nodesObjHash.values();

        // SEA子系统梁可视化对象。
        objs << m_SEABeamObjHash.values();

#if SUBSYSTEM_MERGE
        // SEA子系统壳（板）可视化对象。
        objs << m_SEAShellsObjHash.values();

        // SEA子系统声腔可视化对象。
        objs << m_SEACavitiesObjHash.values();
#else
        // SEA子系统壳（板）可视化对象。
        objs << m_SEAShellObjHash.values();

        // SEA子系统声腔可视化对象。
        objs << m_SEACavityObjHash.values();
#endif

        // SEA子系统半无限流体可视化对象。
        objs << m_SEASemiInfFluidObjHash.values();
        
        return objs;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getCurrentCameraSenGraphObjs()
    {
        // 当前所有相机敏感可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // SEA子系统半无限流体可视化对象。
        objs << m_SEASemiInfFluidObjHash.values();

        return objs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getModelGraphObject(int dataObjId)
    {
        // 模型可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Interface::FITKAbsGeoCommand* model = FITKDATAREPO->getTDataByID<Interface::FITKAbsGeoCommand>(dataObjId);
        if (!model)
        {
            return obj;
        }

        // 模型可视化对象。
        obj = getGraphObject("GeoModel", m_geoObjHash, model);

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllModelGraphObjects(bool autoCreate)
    {
        if (autoCreate)
        {
            // 创建所有可实例化几何模型可视化对象。
            if (m_geoCmdList)
            {
                QList<Interface::FITKAbsGeoCommand*> cmds = m_geoCmdList->getRootCommandList();
                for (Interface::FITKAbsGeoCommand* cmd : cmds)
                {
                    // 实例化模型可视化对象。
                    getGraphObject("GeoModel", m_geoObjHash, cmd);
                }
            }
        }

        return m_geoObjHash.values();
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getMeshGraphObject(int dataObjId)
    {
        // 部件网格可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        AbaqusData::FITKAbaqusPart* part = FITKDATAREPO->getTDataByID<AbaqusData::FITKAbaqusPart>(dataObjId);
        if (!part)
        {
            return obj;
        }

        // 部件网格可视化对象。
        obj = getGraphObject("MeshPart", m_meshObjHash, part);

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllMeshGraphObjects(bool autoCreate)
    {
        if (autoCreate)
        {
            // 创建所有网格部件可视化对象。
            if (m_partMgr)
            {
                int nParts = m_partMgr->getDataCount();
                for (int i = 0; i < nParts; i++)
                {
                    AbaqusData::FITKAbaqusPart* part = m_partMgr->getDataByIndex(i);

                    // 实例化网格可视化对象。
                    getGraphObject("MeshPart", m_meshObjHash, part);
                }
            }
        }

        return m_meshObjHash.values();
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getDiscNodesGraphObject()
    {
        // SEA模型节点可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        if (!m_discModel)
        {
            return obj;
        }

        // 获取SEA模型数据。
        Acoustics::FITKAcousticsDiscNodeList* nodes = m_discModel->getNodes();
        if (!nodes)
        {
            return obj;
        }

        // SEA模型节点可视化对象。
        obj = getGraphObject("DiscNodes", m_nodesObjHash, nodes);

        return obj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getSEABeamGraphObject(int dataObjId)
    {
        // SEA子系统梁可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKSEASubSysBeam* beam = FITKDATAREPO->getTDataByID<Acoustics::FITKSEASubSysBeam>(dataObjId);
        if (!beam)
        {
            return obj;
        }

        // SEA子系统梁可视化对象。
        obj = getGraphObject("SEABeam", m_SEABeamObjHash, beam);

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSEABeamGraphObjects(bool autoCreate)
    {
        if (!m_seaSubSysMgr)
        {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate)
        {
            // 创建所有SEA子系统梁可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);

                // 实例化SEA子系统梁可视化对象。
                getGraphObject("SEABeam", m_SEABeamObjHash, subSys);
            }
        }

        return m_SEABeamObjHash.values();
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getSEAShellGraphObject(int dataObjId, bool forceUpdate)
    {
        // SEA子系统壳（板）可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKAbstractSEASubSysShell* shell = FITKDATAREPO->getTDataByID<Acoustics::FITKAbstractSEASubSysShell>(dataObjId);
        if (!shell)
        {
            return obj;
        }

#if SUBSYSTEM_MERGE        
        Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = shell->getSEASubSysType();

        // SEA子系统壳（板）可视化对象。
        switch (ssType)
        {
        case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
            obj = getGraphObjectByKey("SEAFlatShells", m_SEAShellsObjHash, m_seaModel, 
                Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);
            break;
        case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
            obj = getGraphObjectByKey("SEASingleShells", m_SEAShellsObjHash, m_seaModel, 
                Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);
            break;
        case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
            obj = getGraphObjectByKey("SEADoubleShells", m_SEAShellsObjHash, m_seaModel, 
                Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);
            break;
        case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
            obj = getGraphObjectByKey("SEACylinderShells", m_SEAShellsObjHash, m_seaModel,
                Acoustics::FITKAbstractSEASubSys::SEACylinderShell);
            break;
        default:
            break;
        }

        // 局部刷新数据。
        if (obj)
        {
            obj->updateById(dataObjId, forceUpdate);
        }
#else
        // SEA子系统壳（板）可视化对象。
        obj = getGraphObject("SEAShell", m_SEAShellObjHash, shell);
#endif

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSEAShellGraphObjects(bool autoCreate)
    {
        if (!m_seaSubSysMgr)
        {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }


#if SUBSYSTEM_MERGE
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // 实例化SEA子系统壳（板）可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* objFlat = getGraphObjectByKey("SEAFlatShells", m_SEAShellsObjHash,
            m_seaModel, Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);
        Exchange::FITKAcousticsVTKGraphObject3D* objSC = getGraphObjectByKey("SEASingleShells", m_SEAShellsObjHash, 
            m_seaModel, Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);
        Exchange::FITKAcousticsVTKGraphObject3D* objDC = getGraphObjectByKey("SEADoubleShells", m_SEAShellsObjHash,
            m_seaModel, Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);
        Exchange::FITKAcousticsVTKGraphObject3D* objCy = getGraphObjectByKey("SEACylinderShells", m_SEAShellsObjHash,
            m_seaModel, Acoustics::FITKAbstractSEASubSys::SEACylinderShell);

        if (objFlat)
        {
            objs.push_back(objFlat);
        }

        if (objSC)
        {
            objs.push_back(objSC);
        }

        if (objDC)
        {
            objs.push_back(objDC);
        }

        if (objCy)
        {
            objs.push_back(objCy);
        }

        if (autoCreate)
        {
            // 创建所有SEA子系统壳（板）可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();

                // 刷新数据。
                switch (ssType)
                {
                case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
                {
                    if (objFlat)
                    {
                        objFlat->updateById(subSys->getDataObjectID());
                    }
                    break;
                }
                case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
                {
                    if (objSC)
                    {
                        objSC->updateById(subSys->getDataObjectID());
                    }
                    break;
                }
                case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
                {
                    if (objDC)
                    {
                        objDC->updateById(subSys->getDataObjectID());
                    }
                    break;
                }
                case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
                {
                    if (objCy)
                    {
                        objCy->updateById(subSys->getDataObjectID());
                    }
                    break;
                }
                default:
                    break;
                } 
            }
        }

        return objs;
#else
        if (autoCreate)
        {
            // 创建所有SEA子系统壳（板）可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);

                // 实例化SEA子系统壳（板）可视化对象。
                getGraphObject("SEAShell", m_SEAShellObjHash, subSys);
    }
        }

        return m_SEAShellObjHash.values();
#endif
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getSEACavityGraphObject(int dataObjId, bool forceUpdate)
    {
        // SEA子系统声腔可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

#if SUBSYSTEM_MERGE
        obj = getGraphObjectByKey("SEACavities", m_SEACavitiesObjHash, m_seaModel, 
            Acoustics::FITKAbstractSEASubSys::SEACavity);
        if (!obj)
        {
            return nullptr;
        }

        obj->updateById(dataObjId, forceUpdate);

        return obj;
#else
        // 检查数据ID。
        Acoustics::FITKSEASubSysCavity* cavity = FITKDATAREPO->getTDataByID<Acoustics::FITKSEASubSysCavity>(dataObjId);
        if (!cavity)
        {
            return obj;
        }

        // SEA子系统声腔可视化对象。
        obj = getGraphObject("SEACavity", m_SEACavityObjHash, cavity);
#endif

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSEACavityGraphObjects(bool autoCreate)
    {
        if (!m_seaSubSysMgr)
        {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

#if SUBSYSTEM_MERGE
        Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEACavities", m_SEACavitiesObjHash, 
            m_seaModel, Acoustics::FITKAbstractSEASubSys::SEACavity);
        if (!obj)
        {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate)
        {
            // 创建所有SEA子系统声腔可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 实例化SEA子系统声腔可视化对象。
                if (subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEACavity)
                {
                    obj->updateById(subSys->getDataObjectID());
                }
            }
        }

        return m_SEACavitiesObjHash.values();
#else
        if (autoCreate)
        {
            // 创建所有SEA子系统声腔可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);

                // 实例化SEA子系统声腔可视化对象。
                getGraphObject("SEACavity", m_SEACavityObjHash, subSys);
            }
        }

        return m_SEACavityObjHash.values();
#endif
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getSEASemiInfFluidGraphObject(int dataObjId)
    {
        // SEA子系统半无限流体可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKSEASubSysSemiInfiniteFluid* semiInfFluid = FITKDATAREPO->getTDataByID<Acoustics::FITKSEASubSysSemiInfiniteFluid>(dataObjId);
        if (!semiInfFluid)
        {
            return obj;
        }

        // SEA子系统半无限流体可视化对象。
        obj = getGraphObject("SEASemiInfFluid", m_SEASemiInfFluidObjHash, semiInfFluid);

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSEASemiInfFluidGraphObjects(bool autoCreate)
    {
        if (!m_seaSubSysMgr)
        {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate)
        {
            // 创建所有子系统半无限流体可视化对象。
            int nSubSys = m_seaSubSysMgr->getDataCount();
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);

                // 实例化子系统半无限流体可视化对象。
                getGraphObject("SEASemiInfFluid", m_SEASemiInfFluidObjHash, subSys);
            }
        }

        return m_SEASemiInfFluidObjHash.values();
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getSEASubSysGraphObject(int dataObjId, bool forceUpdate)
    {
        // SEA子系统可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKAbstractSEASubSys* subSys = FITKDATAREPO->getTDataByID<Acoustics::FITKAbstractSEASubSys>(dataObjId);
        if (!subSys)
        {
            return obj;
        }
        
        Acoustics::FITKAbstractSEASubSys::SEASubSysType subSysType = subSys->getSEASubSysType();
        switch (subSysType)
        {
        case Acoustics::FITKAbstractSEASubSys::SEABeam:
        {
            Acoustics::FITKSEASubSysBeam* beam = dynamic_cast<Acoustics::FITKSEASubSysBeam*>(subSys);
            if (beam)
            {
                // 实例化子系统梁可视化对象。
                obj = getGraphObject("SEABeam", m_SEABeamObjHash, beam);
            }

            break;
        }
#if SUBSYSTEM_MERGE
        case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
        {
            // 实例化SEA子系统平板可视化对象。
            obj = getGraphObjectByKey("SEAFlatShells", m_SEAShellsObjHash, m_seaModel, 
                Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);

            // 刷新数据。
            if (obj)
            {
                obj->updateById(subSys->getDataObjectID(), forceUpdate);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
        {
            // 实例化SEA子系统单曲率可视化对象。
            obj = getGraphObjectByKey("SEASingleShells", m_SEAShellsObjHash, m_seaModel,
                Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);

            // 刷新数据。
            if (obj)
            {
                obj->updateById(subSys->getDataObjectID(), forceUpdate);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
        {
            // 实例化SEA子系统双曲率板可视化对象。
            obj = getGraphObjectByKey("SEADoubleShells", m_SEAShellsObjHash, m_seaModel,
                Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);

            // 刷新数据。
            if (obj)
            {
                obj->updateById(subSys->getDataObjectID(), forceUpdate);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
        {
            // 实例化SEA子系统圆柱板可视化对象。
            obj = getGraphObjectByKey("SEACylinderShells", m_SEAShellsObjHash, m_seaModel,
                Acoustics::FITKAbstractSEASubSys::SEACylinderShell);

            // 刷新数据。
            if (obj)
            {
                obj->updateById(subSys->getDataObjectID(), forceUpdate);
            }

            break;
        }
#else
        case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
        case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
        case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
        case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
        {
            Acoustics::FITKAbstractSEASubSysShell* shell = dynamic_cast<Acoustics::FITKAbstractSEASubSysShell*>(subSys);
            if (shell)
            {
                // 实例化SEA子系统壳（板）可视化对象。
                obj = getGraphObject("SEAShell", m_SEAShellObjHash, shell);
            }
            break;
        }
#endif
        case Acoustics::FITKAbstractSEASubSys::SEACavity:
        {
#if SUBSYSTEM_MERGE
            // 实例化SEA子系统壳（板）可视化对象。
            obj = getGraphObjectByKey("SEACavities", m_SEACavitiesObjHash, 
                m_seaModel, Acoustics::FITKAbstractSEASubSys::SEACavity);

            // 刷新数据。
            if (obj)
            {
                obj->updateById(subSys->getDataObjectID(), forceUpdate);
            }
#else
            Acoustics::FITKSEASubSysCavity* cavity = dynamic_cast<Acoustics::FITKSEASubSysCavity*>(subSys);
            if (cavity)
            {
                // 实例化SEA子系统腔室可视化对象。
                obj = getGraphObject("SEACavity", m_SEACavityObjHash, cavity);
            }
#endif

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid:
        {
            Acoustics::FITKSEASubSysSemiInfiniteFluid* semiInfFluid = dynamic_cast<Acoustics::FITKSEASubSysSemiInfiniteFluid*>(subSys);
            if (semiInfFluid)
            {
                // 实例化SEA子系统半无限流体可视化对象。
                obj = getGraphObject("SEASemiInfFluid", m_SEASemiInfFluidObjHash, semiInfFluid);
            }

            break;
        }
        default:
            return obj;
        }

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSEASubSysGraphObjects(bool autoCreate)
    {
        return getAllSEABeamGraphObjects(autoCreate) + 
            getAllSEAShellGraphObjects(autoCreate) +
            getAllSEACavityGraphObjects(autoCreate) +
            getAllSEASemiInfFluidGraphObjects(autoCreate);
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getSEASubSysGraphObjectsByType(int subSysTypeEnum, bool update)
    {
        // SEA子系统可视化对象列表。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        if (!m_seaSubSysMgr)
        {
            return objs;
        }

        // 创建对应类型子系统可视化对象。
        int nSubSys = m_seaSubSysMgr->getDataCount();

#if SUBSYSTEM_MERGE
        // Lambda.
        auto updateMergedObj = [=](Exchange::FITKAcousticsVTKGraphObject3D* obj)
        {
            // 平板 & 单曲率板 & 双曲率板 & 圆柱板。
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 获取SEA子系统类型。
                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();
                if (ssType != subSysTypeEnum)
                {
                    continue;
                }

                // 刷新数据。
                obj->updateById(subSys->getDataObjectID());
            }
        };
#endif

        switch (subSysTypeEnum)
        {           
        case Acoustics::FITKAbstractSEASubSys::SEABeam:
        {
            // 梁。
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 获取SEA子系统类型。
                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();
                if (ssType != subSysTypeEnum)
                {
                    continue;
                }

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("SEABeam", m_SEABeamObjHash, subSys);
                if (obj)
                {
                    objs.push_back(obj);
                }
            }

            break;
        }
#if SUBSYSTEM_MERGE
        case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
        {
            // 实例化SEA子系统平板可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEAFlatShells", m_SEAShellsObjHash,
                m_seaModel, Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);
            if (!obj)
            {
                break;
            }

            objs.push_back(obj);

            if (update)
            {
                updateMergedObj(obj);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
        {
            // 实例化SEA子系统单曲率板可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEASingleShells", m_SEAShellsObjHash, 
                m_seaModel, Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);
            if (!obj)
            {
                break;
            }

            objs.push_back(obj);

            if (update)
            {
                updateMergedObj(obj);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
        {
            // 实例化SEA子系统双曲率板可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEADoubleShells", m_SEAShellsObjHash,
                m_seaModel, Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);
            if (!obj)
            {
                break;
            }

            objs.push_back(obj);

            if (update)
            {
                updateMergedObj(obj);
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
        {
            // 实例化SEA子系统圆柱板可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEACylinderShells", m_SEAShellsObjHash,
                m_seaModel, Acoustics::FITKAbstractSEASubSys::SEACylinderShell);
            if (!obj)
            {
                break;
            }

            objs.push_back(obj);

            if (update)
            {
                updateMergedObj(obj);
            }

            break;
        }
#else
        case Acoustics::FITKAbstractSEASubSys::SEAFlatPlate:
        case Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell:
        case Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell:
        case Acoustics::FITKAbstractSEASubSys::SEACylinderShell:
        {
            // 平板 & 单曲率板 & 双曲率板 & 圆柱板。
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 获取SEA子系统类型。
                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();
                if (ssType != subSysTypeEnum)
                {
                    continue;
                }

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("SEAShell", m_SEAShellObjHash, subSys);
                if (obj)
                {
                    objs.push_back(obj);
                }
            }
            break;
        }
#endif
        case Acoustics::FITKAbstractSEASubSys::SEACavity:
        {
#if SUBSYSTEM_MERGE
            // 实例化SEA子系统声腔可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEACavities", m_SEACavitiesObjHash, m_seaModel
                , Acoustics::FITKAbstractSEASubSys::SEACavity);

            // 刷新数据。
            if (!obj)
            {
                break;
            }

            objs.push_back(obj);

            if (update)
            {
                updateMergedObj(obj);
            }
#else
            // 声腔。
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 获取SEA子系统类型。
                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();
                if (ssType != subSysTypeEnum)
                {
                    continue;
                }

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("SEACavity", m_SEACavityObjHash, subSys);
                if (obj)
                {
                    objs.push_back(obj);
                }
            }
#endif

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid:
        {
            // 半无限流体。
            for (int i = 0; i < nSubSys; i++)
            {
                Acoustics::FITKAbstractSEASubSys* subSys = m_seaSubSysMgr->getDataByIndex(i);
                if (!subSys)
                {
                    continue;
                }

                // 获取SEA子系统类型。
                Acoustics::FITKAbstractSEASubSys::SEASubSysType ssType = subSys->getSEASubSysType();
                if (ssType != subSysTypeEnum)
                {
                    continue;
                }

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("SEASemiInfFluid", m_SEASemiInfFluidObjHash, subSys);
                if (obj)
                {
                    objs.push_back(obj);
                }
            }

            break;
        }
        case Acoustics::FITKAbstractSEASubSys::SEASSNone:
        default:
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        return objs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphModelProvider::getFEFaceGraphObject(int dataObjId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;

        graphObj = getGraphObject("FEFaces", m_feFaceObjHash, m_feModel);

        // 局部刷新数据。
        if (graphObj) {
            graphObj->updateById(dataObjId, forceUpdate);
        }

        return graphObj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphModelProvider::getFEShellGraphObject(int dataObjId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;

        graphObj = getGraphObject("FEShells", m_feShellObjHash, m_feModel);

        // 局部刷新数据。
        if (graphObj) {
            graphObj->updateById(dataObjId, forceUpdate);
        }

        return graphObj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphModelProvider::getFEBeamGraphObject(int dataObjId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;

        graphObj = getGraphObject("FEBeams", m_feBeamObjHash, m_feModel);

        // 局部刷新数据。
        if (graphObj) {
            graphObj->updateById(dataObjId, forceUpdate);
        }

        return graphObj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphModelProvider::getFEAcousticGraphObject(int dataObjId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;

        graphObj = getGraphObject("FEAcoustic", m_feAcousticObjHash, m_feModel);

        // 局部刷新数据。
        if (graphObj) {
            graphObj->updateById(dataObjId, forceUpdate);
        }

        return graphObj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphModelProvider::getSensorGraphObject(int dataObjId)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;
        Acoustics::FITKAcousticsSensors* sensor = FITKDATAREPO->getTDataByID<Acoustics::FITKAcousticsSensors>(dataObjId);
        if (sensor == nullptr)return nullptr;

        graphObj = getGraphObject("Sensor", m_sensorObjHash, sensor);

        return graphObj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllFESubSysGraphObjects(bool autoCreate)
    {
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> grphObjList = {};
        grphObjList.append(getFEStructGraphObjects(autoCreate));
        grphObjList.append(getFEAcousticsGraphObjects(autoCreate));
        return grphObjList;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllFEFaceGraphObjects(bool autoCreate)
    {
        if (m_feModel == nullptr || m_feModel->getFEFaceManager() == nullptr) {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate){
            // 创建所有FE面可视化对象。
            int nSubSys = m_feModel->getFEFaceManager()->getDataCount();
            for (int i = 0; i < nSubSys; i++){
                Acoustics::FITKAcousticsFEFace* feFace = m_feModel->getFEFaceManager()->getDataByIndex(i);
                if (feFace == nullptr)continue;

                // 实例化FE面可视化对象。
                Exchange::FITKAcousticsVTKGraphObject3D* graphObj = getGraphObject("FEFaces", m_feFaceObjHash, m_feModel);
                if (graphObj) {
                    graphObj->updateById(feFace->getDataObjectID(), autoCreate);
                }
            }
        }

        return m_feFaceObjHash.values();
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getFEStructGraphObjects(bool autoCreate)
    {
        if (m_feModel == nullptr || m_feModel->getFESubSysManager() == nullptr) {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate) {
            // 创建所有FE结构可视化对象。
            for (Acoustics::FITKAbstractFESubSys* feSubSys: m_feModel->getFESubSysManager()->getSubSysByType(Acoustics::FITKAbstractFESubSys::FESubSysType::FEStructure)) {
                if (feSubSys == nullptr)continue;

                // 实例化FE结构可视化对象。
                Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;
                
                if (feSubSys->getElementDim() == 1) {
                    graphObj = getGraphObject("FEBeams", m_feBeamObjHash, m_feModel);
                }
                else if(feSubSys->getElementDim() == 2) {
                    graphObj = getGraphObject("FEShells", m_feShellObjHash, m_feModel);
                }

                // 局部刷新数据。
                if (graphObj) {
                    graphObj->updateById(feSubSys->getDataObjectID(), autoCreate);
                }
            }
        }

        return m_feBeamObjHash.values() + m_feShellObjHash.values();
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getFEAcousticsGraphObjects(bool autoCreate)
    {
        if (m_feModel == nullptr || m_feModel->getFESubSysManager() == nullptr) {
            return QList<Exchange::FITKAcousticsVTKGraphObject3D*>();
        }

        if (autoCreate) {
            // 创建所有FE声腔可视化对象。
            for (Acoustics::FITKAbstractFESubSys* feSubSys : m_feModel->getFESubSysManager()->getSubSysByType(Acoustics::FITKAbstractFESubSys::FESubSysType::FEAcoustic)) {
                if (feSubSys == nullptr)continue;

                // 实例化FE声腔可视化对象。
                Exchange::FITKAcousticsVTKGraphObject3D* graphObj = getGraphObject("FEAcoustic", m_feAcousticObjHash, m_feModel);
                // 局部刷新数据。
                if (graphObj) {
                    graphObj->updateById(feSubSys->getDataObjectID(), autoCreate);
                }
            }
        }

        return m_feAcousticObjHash.values();
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getFEFaceGraphObjects(bool autoCreate)
    {
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> grphObjList = {};
        if (m_feModel == nullptr)return grphObjList;

        //FE面
        if (autoCreate) {
            for (int i = 0; i < m_feModel->getFEFaceManager()->getDataCount(); i++) {
                Acoustics::FITKAcousticsFEFace* face = m_feModel->getFEFaceManager()->getDataByIndex(i);
                if (face == nullptr)continue;
                grphObjList.append(getFEFaceGraphObject(face->getDataObjectID()));
            }
        }
        return grphObjList;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphModelProvider::getAllSensorGraphObjects(bool autoCreate)
    {
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> grphObjList = {};
        if (m_feModel == nullptr)return grphObjList;

        //FE传感器
        for (int i = 0; i < m_feModel->getSensorManager()->getDataCount(); i++) {
            Acoustics::FITKAcousticsSensors* sensor = m_feModel->getSensorManager()->getDataByIndex(i);
            if (sensor == nullptr)continue;
            Exchange::FITKAcousticsVTKGraphObject3D* graphObj = getSensorGraphObject(sensor->getDataObjectID());
            if (graphObj == nullptr)continue;
            if (autoCreate) {
                graphObj->updateById(sensor->getDataObjectID(), autoCreate);
            }
            grphObjList.append(graphObj);
        }
        return grphObjList;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphModelProvider::getCurrentGraphObjByDataId(int dataObjId)
    {
        // 查找模型。
        if (m_geoObjHash.contains(dataObjId))
        {
            return m_geoObjHash[dataObjId];
        }

        // 查找网格。
        if (m_meshObjHash.contains(dataObjId))
        {
            return m_meshObjHash[dataObjId];
        }

        // 查找SEA模型节点。
        if (m_nodesObjHash.contains(dataObjId))
        {
            return m_nodesObjHash[dataObjId];
        }

        // 查找SEA子系统梁节点。
        if (m_SEABeamObjHash.contains(dataObjId))
        {
            return m_SEABeamObjHash[dataObjId];
        }

#if SUBSYSTEM_MERGE
        // TODO SEA子系统查询
        //// 查找SEA子系统壳（板）节点。
        //if (m_SEAShellsObjHash.contains(dataObjId))
        //{
        //    return m_SEAShellsObjHash[dataObjId];
        //}

        //// 查找SEA子系统腔节点。
        //if (m_SEACavitiesObjHash.contains(dataObjId))
        //{
        //    return m_SEACavitiesObjHash[dataObjId];
        //}
#else
        // 查找SEA子系统壳（板）节点。
        if (m_SEAShellObjHash.contains(dataObjId))
        {
            return m_SEAShellObjHash[dataObjId];
        }

        // 查找SEA子系统腔节点。
        if (m_SEACavityObjHash.contains(dataObjId))
        {
            return m_SEACavityObjHash[dataObjId];
        }
#endif

        // 查找子系统半无限流体节点。
        if (m_SEASemiInfFluidObjHash.contains(dataObjId))
        {
            return m_SEASemiInfFluidObjHash[dataObjId];
        }

        return nullptr;
    }

    void GraphModelProvider::setDoubleClickPickable(bool pickable)
    {
        // 梁 & 板 & 声腔 & 半无限流体 子系统 & FE面 & FE结构 & FE声腔 & FE传感器
        setSEABeamPickable(pickable);
        setSEAShellPickable(pickable);
        setSEACavityPickable(pickable);
        setSEASemiInfFluidPickable(pickable);
        setFEFacePickable(pickable);
        setFEShellsPickable(pickable);
        setFEBeamsPickable(pickable);
        setFEAcousticPickable(pickable);
        setSensorsPickable(pickable);
    }

    void GraphModelProvider::setGeoVertPickable(int dataObjId)
    {
        // 开启可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickVertex);
            }
        }
    }

    void GraphModelProvider::setGeoEdgePickable(int dataObjId)
    {
        // 开启可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickEdge);
            }
        }
    }

    void GraphModelProvider::setGeoFacePickable(int dataObjId)
    {
        // 开启可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickFace);
            }
        }
    }

    void GraphModelProvider::setGeoSolidPickable(int dataObjId)
    {
        // 开启可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickSolid);
            }
        }
    }

    void GraphModelProvider::setGeoPickable(int dataObjId)
    {
        // 开启可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll);
            }
        }
    }

    void GraphModelProvider::setGeoNonePickable(int dataObjId)
    {
        // 关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_geoObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                // 其他数据不取消拾取。
                continue;
            }
            else
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
        }
    }

    void GraphModelProvider::setMeshCellPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickElement :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_meshObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setDiscNodesPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNode :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_nodesObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setSEABeamPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll : // PickEdge
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEABeamObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setSEAShellPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll : // PickFace
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
#if SUBSYSTEM_MERGE
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEAShellsObjHash.values();
#else
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEAShellObjHash.values();
#endif
       
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setSEACavityPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll : // PickSolid
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
#if SUBSYSTEM_MERGE
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEACavitiesObjHash.values();
#else
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEACavityObjHash.values();
#endif
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setSEASemiInfFluidPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEASemiInfFluidObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setFEFacePickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ? Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll 
            : Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_feFaceObjHash.values();

        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs){
            if (obj == nullptr)continue;

            if (obj->getDataId() != dataObjId && dataObjId != -1){
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else{
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setFEShellsPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ? Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll
            : Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_feShellObjHash.values();

        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            if (obj == nullptr)continue;

            if (obj->getDataId() != dataObjId && dataObjId != -1) {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setFEBeamsPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ? Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll
            : Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_feBeamObjHash.values();

        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            if (obj == nullptr)continue;

            if (obj->getDataId() != dataObjId && dataObjId != -1) {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setFEAcousticPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ? Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll
            : Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_feAcousticObjHash.values();

        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            if (obj == nullptr)continue;

            if (obj->getDataId() != dataObjId && dataObjId != -1) {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphModelProvider::setSensorsPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ? Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll
            : Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_sensorObjHash.values();

        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            if (obj == nullptr)continue;

            if (obj->getDataId() != dataObjId && dataObjId != -1) {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else {
                obj->setPickMode(pickMode);
            }
        }
    }
}   // namespace GraphData